import os
import random


from appium.webdriver.webdriver import WebDriver
from selenium.common import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

from utils.error_handle import black_wrapper
from utils.log_util import logger
from utils.utils import Utils


class BasePage:
    def __init__(self,driver:WebDriver = None):
        self.driver = driver

    # 找元素
    @black_wrapper
    def find(self, by, value):
        # logger.info(f"定位的元素为{by,value}")
        return self.driver.find_element(by, value)

    # 查找多个元素
    @black_wrapper
    def finds(self, by, value):
        logger.info(f"定位的元素为{by, value}")
        # 返回一个列表
        return self.driver.find_elements(by, value)

    # 找到并点击
    def find_and_click(self, by, value):
        logger.info(f"点击的元素为{by, value}")
        self.find(by, value).click()

    # 找到并获取元素文本
    def find_and_text(self, by, value):
        logger.info(f"获取文本的元素为{by, value}")
        return self.find(by, value).text

    # 清空输入框
    def find_and_clear(self,by,value):
        logger.info(f"清空数据定位的元素为{by, value}")
        self.find(by,value).clear()

    # 找到并输入信息
    def find_and_send_keys(self, by, value, text: str):
        logger.info(f"输入数据定位的元素为{by, value}")
        self.find(by,value).send_keys(text)

    # 随机选择性别
    def choose_sex(self):
        logger.info(f"随机选择性别")
        sex = ['男', '女']
        # 随机性别
        sex_result = random.choice(sex)
        # 点击性别
        self.driver.find_element(By.XPATH, "//*[@text='性别']/parent::*/child::*[2]").click()
        # 随机选择性别
        ctrl2 = self.wait_for_text(self.driver, sex_result)
        if ctrl2 == True:
            self.driver.find_element(By.XPATH, f'//*[@text="{sex_result}"]').click()

    # 滑动直到找到元素
    def swipe_element(self, by, value):
        logger.info(f"滑动直到定位到元素为{by, value}")
        # 设置隐式等待时间
        self.driver.implicitly_wait(2)
        while True:
            add_member = self.driver.find_elements(by, value)
            if len(add_member) < 1:
                # 获取屏幕的宽和高
                window_size = self.driver.get_window_size()
                # 从window_size中获取width的值
                width = window_size["width"]
                # 从window_size中获取height的值
                height = window_size["height"]
                # 宽度除以2,获取中心点位置
                startx = int(width / 2)
                # 从屏幕下方开始滑动
                starty = height * 0.8
                # 滑动结束的位置
                endy = height * 0.2
                # 滑动的时间(毫秒)
                duration = 200
                # 开始位置的坐标,滑动结束的坐标,滑动的时间
                self.driver.swipe(start_x=startx, start_y=starty, end_x=startx, end_y=endy, duration=duration)
            else:
                return add_member[0]

    # 获取 toast 文本
    def get_toast_text(self):
        tipe = self.driver.find_element(By.XPATH, "//*[@class='android.widget.Toast']").text
        logger.info(f"获取到的toast文本为{tipe}")
        return tipe
    # 显示等待某个元素可见
    def wait_for_element_visible(self, ele):
        logger.info(f"显示等待{ele}元素可见")
        WebDriverWait(self.driver,10).until(
            expected_conditions.visibility_of_element_located(ele)
        )

    def wait_for_text(self,driver, text, time=5):
        logger.info(f"显示等待'{text}'出现")
        try:
            WebDriverWait(driver, time).until(
                expected_conditions.visibility_of_element_located((By.XPATH, f"//*[@text='{text}']")),
                message=f"{text}没找到"
            )
            return True
        except TimeoutException:
            return False
    # 显示等待某个元素可以被点击
    def wait_for_click(self,driver, by, value, time=10):
        logger.info(f"显示等待定位元素{by, value}可以点击")
        try:
            WebDriverWait(driver, time).until(
                expected_conditions.element_to_be_clickable((by, value))
            )
            return True
        except TimeoutException:
            return False
    # 一直点返回直到出现通讯录
    def back_main(self):
        self.driver.implicitly_wait(1)
        res = self.wait_for_text(self.driver, "通讯录",1)
        while res == False:
            self.find_and_click(By.XPATH, "//*[@resource-id='com.tencent.wework:id/l5w']")
            res = self.wait_for_text(self.driver, "通讯录",1)

    def wait(self,num):
        self.driver.implicitly_wait(num)

    def screenshot(self, root_path):
        '''
        截图
        :param root_path: 项目路径
        :return 截图保存路径
        '''
        logger.info("完成截操作")
        # 以当前时间命名的截图
        image_name = Utils.get_current_time() + ".png"
        # 拼接当前要输出图片的路径
        image_dir_path = os.sep.join([root_path, '..', f'images/'])
        # images 目录如果不存在则新创建一个
        if not os.path.isdir(image_dir_path):
            os.mkdir(image_dir_path)
        # 拼接图片保存目录
        image_path = image_dir_path + image_name
        logger.info(f"截图路径为：{image_path}")
        # 截图
        self.driver.save_screenshot(image_path)
        # 返回保存图片的路径
        return image_path

    def save_page_source(self, root_path):
        '''
        保存页面源码
        :return: 返回源码文件路径
        '''
        logger.info("保存页面源码")
        # 以当前时间命名的 page source
        page_source_name = Utils.get_current_time() + "_page_source.xml"
        # 拼接当前要输出文件的路径
        page_source_dir_path = os.sep.join([root_path, '..', f'page_source/'])
        # 路径不存在则新创建一个
        if not os.path.isdir(page_source_dir_path):
            os.mkdir(page_source_dir_path)
        # 拼接 page source 保存路径
        page_source_path = page_source_dir_path + page_source_name
        logger.info(f"page source 路径为：{page_source_path}")
        # 写 page source 文件
        with open(page_source_path, "w", encoding="u8") as f:
            f.write(self.driver.page_source)
        # 返回 page source 保存路径
        return page_source_path
